package com.duowan.cms.service.article;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.duowan.cms.common.domain.Page;
import com.duowan.cms.common.exception.BaseCheckedException;
import com.duowan.cms.common.service.DoToDtoConvertorFactory;
import com.duowan.cms.common.util.StringUtil;
import com.duowan.cms.core.rmi.client.article.Article4TagListRemoteService;
import com.duowan.cms.domain.article.Article;
import com.duowan.cms.domain.article.Article4TagList;
import com.duowan.cms.domain.article.rpst.Article4TagListRepository;
import com.duowan.cms.domain.article.rpst.ArticleRepository;
import com.duowan.cms.domain.tag.rpst.TagRepository;
import com.duowan.cms.dto.article.Article4TagListInfo;
import com.duowan.cms.dto.article.Article4TagListSearchCriteria;
import com.duowan.cms.dto.article.ArticleInfo;
import com.duowan.cms.dto.tag.TagInfo;
import com.duowan.cms.service.article.util.ArticlePublisher;

@Service("article4TagListService")
public class Article4TagListServiceImpl implements Article4TagListService, Article4TagListRemoteService {

    @Autowired
    private Article4TagListRepository article4TagListRepository;
    //@Autowired
    //private ChannelService channelService;
    @Autowired
    private ArticleRepository articleRepository;
    
    @Autowired
    private TagRepository tagRepository;

    @SuppressWarnings("unchecked")
    @Override
    public Article4TagListInfo getByPrimaryKey(String channelId, String tag, Long articleId) {
        Article4TagList article4TagList = article4TagListRepository.getByPrimaryKey(channelId, tag, articleId);
        return (Article4TagListInfo) DoToDtoConvertorFactory.getConvertor(Article4TagList.class).do2Dto(article4TagList);
    }

    @Override
    public void publishEmptyLink(Article4TagListInfo article4TagListInfo) throws BaseCheckedException {
        String channelId = article4TagListInfo.getChannelInfo().getId();
        String tag = article4TagListInfo.getTag();
        Long articleId = article4TagListInfo.getId();
        Article4TagList article4TagList = article4TagListRepository.getByPrimaryKey(channelId, tag, articleId);
        if (article4TagList == null) {
            article4TagList = new Article4TagList(article4TagListInfo);
            article4TagListRepository.save(article4TagList);
            logger.info("在频道:" + channelId + ",标签:" + tag + "列表下成功保存空链接[articleId=" + article4TagList.getId() + ", articleTitle=" + article4TagList.getTitle() + "]");
        } else {
            logger.info("保存失败!在频道:" + channelId + ",标签:" + tag + "列表下存在文章[articleId=" + article4TagList.getId() + ",articleTitle=" + article4TagList.getTitle() + "]");
        }
    }

    /**
     * 保存某篇文章下的所有"列表文章"数据
     * @param articleInfo
     */
    @Override
    public void saveArticle4TagListInfo(ArticleInfo articleInfo) {
        
        String channelId = articleInfo.getChannelInfo().getId();
        
        List<Article4TagList> newArticle4TagList = new Article(articleInfo).toArticle4TagList();// 提交表单后,生成的"列表文章"数据
        for (Article4TagList newArticle4Tag : newArticle4TagList) {
            //为article4TagList增加sontag和sontagId
            setMatchSontag(channelId, newArticle4Tag, articleInfo.getTags());
            article4TagListRepository.save(newArticle4Tag);// 新增
        }
    }
    
    private void setMatchSontag(String channelId, Article4TagList article4TagList, String tags){
        
        if(StringUtil.isEmpty(tags))
            return;
        if(!tags.startsWith(","))
            tags = "," + tags;
        
        List<TagInfo> list = tagRepository.getChildren(channelId, article4TagList.getTag());
        for(TagInfo tagInfo : list){
            if (tags.indexOf("," + tagInfo.getName() + ",") != -1) {
                article4TagList.setSonTag(tagInfo.getName());
                article4TagList.setSonTagId(tagInfo.getId() + "");
                break;
                }
        }
            
    }

    /**
     *  更新某篇文章下的所有"列表文章"数据：
     *  newArticle4TagList: 提交表单后,得到的tags(界面元素),生成的"列表文章"数据.
     *  preArticle4TagList:进入编辑文章界面(article_edit.jsp)，初化始的tags(界面元素)对应"列表文章"数据
    	newArticle4TagList和preArticle4TagList对比后，会产生四类不同的数据：
    	1.新增数据：preArticle4TagList不存在的标签，而newArticle4TagList存在,则是newArticle4TagList新增进来的标签。
    	2.删除数据：preArticle4TagList存在的标签，但newArticle4TagList不存在。把preArticle4TagList的数据状态标记为"已删除"
    	3.相同数据：preArticle4TagList存在的标签，而newArticle4TagList存在。
    							若preArticle4TagList的数据状态标记为"已删除",则把状态更新为"已激活",并更新"最后更新时间"
    							若preArticle4TagList的数据状态标记为"已激活",则只是更新"最后更新时间"
     */
    @Override
    public void updateArticle4TagListInfo(ArticleInfo articleInfo) {
        
        String channelId = articleInfo.getChannelInfo().getId();
        // 从数据库里获取表单没有传过来但是必须的数据，如publishTime等
        Article articleInDataBae = articleRepository.getByChannelIdAndArticleId(articleInfo.getChannelInfo().getId(), articleInfo.getId());
        List<Article4TagList> newArticle4TagList = articleInDataBae.update(articleInfo).toArticle4TagList();// 提交表单后,生成的"列表文章"数据
        // 上一次提交表单生成的"列表文章"数据（即存于数据库里的"列表文章"）
        List<Article4TagListInfo> preArticle4TagList = article4TagListRepository.getByChannelIdAndArticleId(articleInfo.getChannelInfo().getId(), articleInfo.getId());

        for (Article4TagList newArticle4Tag : newArticle4TagList) {
            
            //设置sontag和sontagid
            setMatchSontag(channelId, newArticle4Tag, articleInfo.getTags());
            
            boolean isExist = false;// 标记newArticle4Tag.getTag()是否已经存在于数据库
            for (Article4TagListInfo article4Tag : preArticle4TagList) {
                // 判断本次提交的标签已存在于数据库
                if (newArticle4Tag.getTag().equals(article4Tag.getTag())) {
                    isExist = true;
                    //更新条件(满足下列条件之一即可)：1.之前的状态为删除;2.文章勾选了"修改所有tag"并且检查到字段发生了变化
                    if (article4Tag.isDelete() || (articleInfo.isChangeAllTags() && isNeedUpdate(article4Tag, newArticle4Tag))) {
                        article4TagListRepository.update(newArticle4Tag);
                    }
                    break;
                }
            }
            if (!isExist) {
                article4TagListRepository.save(newArticle4Tag);// 新增
            }
        }
        String tags = articleInfo.getTags();
        
        if(!StringUtil.isEmpty(tags) && !tags.startsWith(",")){
                tags = ","+tags;
        }
        for (Article4TagListInfo article4Tag : preArticle4TagList) {// 删除
            if ((StringUtil.isEmpty(tags) || tags.indexOf(","+article4Tag.getTag()+",") == -1) && !article4Tag.isDelete()) {
                article4Tag.setDelete(true);
                article4TagListRepository.update(new Article4TagList(article4Tag));
            }
        }
            
        
    }

    //通过对比新旧列表文章，判断列表文章是否需要更新
    private boolean isNeedUpdate(Article4TagListInfo oldArticle4TagListInfo, Article4TagList newArticle4TagList) {

        if (null == oldArticle4TagListInfo || null == newArticle4TagList) {
            logger.warn("isNeedUpdate:one(at least) param of method is null.");
            return false;
        }
        // 旧标签状态为删除，应该更新
        //if (oldArticle4TagListInfo.isDelete())
            //return true;
        // 新的标题更新，应该更新
        if (!isEquals(oldArticle4TagListInfo.getTitle(), newArticle4TagList.getTitle()))
            return true;
        if (!isEquals(oldArticle4TagListInfo.getSubtitle(), newArticle4TagList.getSubtitle()))
            return true;
        //标题颜色，已支持
        if (!isEquals(oldArticle4TagListInfo.getTitleColor(), newArticle4TagList.getTitleColor()))
            return true;
        if (!isEquals(oldArticle4TagListInfo.getSource(), newArticle4TagList.getSource()))
            return true;
        if (!isEquals(oldArticle4TagListInfo.getAuthor(), newArticle4TagList.getAuthor()))
            return true;
        if (!isEquals(oldArticle4TagListInfo.getPictureUrl(), newArticle4TagList.getPictureUrl()))
            return true;
        if (!isEquals(oldArticle4TagListInfo.getDigest(), newArticle4TagList.getDigest()))
            return true;
        if (!isEquals(oldArticle4TagListInfo.getDiy1(), newArticle4TagList.getDiy1()))
            return true;
        if (!isEquals(oldArticle4TagListInfo.getDiy2(), newArticle4TagList.getDiy2()))
            return true;
        if (!isEquals(oldArticle4TagListInfo.getDiy3(), newArticle4TagList.getDiy3()))
            return true;
        if (!isEquals(oldArticle4TagListInfo.getDiy4(), newArticle4TagList.getDiy4()))
            return true;
        if (!isEquals(oldArticle4TagListInfo.getDiy5(), newArticle4TagList.getDiy5()))
            return true;
        return false;
    }

    private boolean isEquals(Object o1, Object o2) {
        if (o1 == null && o2 == null)
            return true;
        if (o1 == null || o2 == null)
            return false;
        return o1.equals(o2);
    }

    @Override
    public void updateArticle4TagListInfo(Article4TagListInfo article4TagListInfo) {
        String channelId = article4TagListInfo.getChannelInfo().getId();
        String tag = article4TagListInfo.getTag();
        Long articleId = article4TagListInfo.getId();
        if (article4TagListInfo.isChangeAllTags()) {
            Article4TagList article4TagList = new Article4TagList(article4TagListInfo);
            article4TagListRepository.updateByChannelIdAndArticleId(article4TagList);
        } else {
            Article4TagList article4TagList = article4TagListRepository.getByPrimaryKey(channelId, tag, articleId);
            this.updateSingleArticle4TagListInfo(article4TagListInfo, article4TagList);
        }
        // 生成空链接
        if (!StringUtil.isEmpty(article4TagListInfo.getEmptyLink())) {
            ArticlePublisher articlePublisher = ArticlePublisher.getInstance();
            articlePublisher.GenerateEmptyLinkFile(article4TagListInfo);
        }

    }

    /**
     * 更新某条
     * @param article4TagListInfo
     * @param article4TagList
     */
    private void updateSingleArticle4TagListInfo(Article4TagListInfo article4TagListInfo, Article4TagList article4TagList) {
        String channelId = article4TagListInfo.getChannelInfo().getId();
        String tag = article4TagListInfo.getTag();
        if (null != article4TagList) {
            article4TagList.update(article4TagListInfo);
            article4TagListRepository.update(article4TagList);
            logger.info("在频道:" + channelId + ",标签:" + tag + "列表下成功更新文章[articleId=" + article4TagList.getId() + ", articleTitle=" + article4TagList.getTitle() + "]");
        } else {
            logger.info("更新失败!在频道:" + channelId + ",标签:" + tag + "列表下不存在文章[articleId=" + article4TagListInfo.getId() + ",articleTitle=" + article4TagListInfo.getTitle() + "]");
        }
    }

    @Override
    public void updatePower(String channelId, String tag, Long articleId, int power) {
        Article4TagList article4TagList = article4TagListRepository.getByPrimaryKey(channelId, tag, articleId);
        article4TagList.setPower(power);
        article4TagListRepository.update(article4TagList);
        logger.info("在频道:" + channelId + ",标签:" + tag + "列表下更新文章(空链接)[articleId=" + articleId + "]文章的权限值为" + power);
    }

    @Override
    public void updateDayNum(String channelId, String tag, Long articleId, int num) {
        Article4TagList article4TagList = article4TagListRepository.getByPrimaryKey(channelId, tag, articleId);
        article4TagList.setDayNum(article4TagList.getDayNum() + num);
        article4TagListRepository.update(article4TagList);
        logger.info("在频道:" + channelId + ",标签:" + tag + "列表下设置文章(空链接)[articleId=" + articleId + "]的天数为" + num);
    }

    @Override
    public void resetDayNum(String channelId, String tag, Long articleId) {
        Article4TagList article4TagList = article4TagListRepository.getByPrimaryKey(channelId, tag, articleId);
        article4TagList.resetDayNum();
        article4TagListRepository.update(article4TagList);
        logger.info("在频道:" + channelId + ",标签:" + tag + "列表下重置文章(空链接)[articleId=" + articleId + "]天数");
    }

    @Override
    public Page<Article4TagListInfo> pageSearch(Article4TagListSearchCriteria searchCriteria) {
        return article4TagListRepository.pageSearch(searchCriteria);
    }

    @Override
    public List<Article4TagListInfo> listSearch(Article4TagListSearchCriteria searchCriteria) {
        return article4TagListRepository.listSearch(searchCriteria);
    }

    @Override
    public List<String> getRecentEffectTagsInArticle(String channelId, int minute) {
        return article4TagListRepository.getRecentEffectTagsInArticle(channelId, minute);
    }

    @Override
    public Integer getArticleCountByChannelIdAndTag(String channelId, String tag) {
        return article4TagListRepository.getArticleCountByChannelIdAndTag(channelId, tag);
    }

    /**
     * 删除:逻辑上删除
     */
    @Override
    public void deleteArticle4TagList(String channelId, String tag, Long articleId) {
        Article4TagListInfo article4TagListInfo = this.getByPrimaryKey(channelId, tag, articleId);
        Article4TagList article4TagList = new Article4TagList(article4TagListInfo);
        article4TagList.setDelete(true);
        article4TagListRepository.update(article4TagList);
        
        //更新文章表的tag信息
        Article article = articleRepository.getByChannelIdAndArticleId(channelId, articleId);
        if(null != article){
            String tags = article.getTags();
            tags = ("," + tags).replace("," + tag + ",", ",");
            if (tags.startsWith(",")) {
                tags = tags.substring(1, tags.length());
            }
            article.setTags(tags);
            articleRepository.update(article);
        }
    }

    /**
     * 根据频道id和文章id批量删除文章列表数据
     */
    @Override
    public void deleteByChannelIdAndArticleId(String channelId, Long articleId) {
        article4TagListRepository.logicDeleteByChannelIdAndArticleId(channelId, articleId);
    }

    @Override
    public boolean checkTitleIsExisted(String channelId, Long articleId, String title, String tag) {
        if (StringUtil.isEmpty(tag)) {
            int count = article4TagListRepository.getCountByTitle(channelId, title);
            if (count > 0) {
                return true;
            }
        } else {
            Article4TagList article4TagList = article4TagListRepository.getByPrimaryKey(channelId, tag, articleId);
            if (article4TagList != null && title.equals(article4TagList.getTitle())) {
                return true;
            }
        }

        return false;
    }

}
